﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data;
using MySql.Data.MySqlClient;
using Eb;
using Es;

public class MySQLRequest
{
    public MySqlConnection con;
    public MySqlCommand cmd;
    public string acc_name;
}

public class DbClientMySQL
{
    //-------------------------------------------------------------------------
    static public DbClientMySQL Instance { get; private set; }
    public string ConStr { get; private set; }

    //-------------------------------------------------------------------------
    public DbClientMySQL()
    {
        Instance = this;
        ConStr = ConfigurationManager.AppSettings["MysqlConfigStr"];
    }

    //-------------------------------------------------------------------------
    public async Task<RegisterResponseData> register(RegisterAccountData register_account_data)
    {
        string name = string.IsNullOrEmpty(register_account_data.name) ? "" : register_account_data.name;
        name = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(name));

        string identity_num = string.IsNullOrEmpty(register_account_data.identity_num) ? "" : register_account_data.identity_num;
        string phone_num = string.IsNullOrEmpty(register_account_data.phone_num) ? "" : register_account_data.phone_num;

        string sql_str = string.Format("INSERT INTO Account SET AccountName='{0}', Password='{1}', Name='{2}', IdentityNum='{3}', PhoneNum='{4}', Sex='{5}';",
            register_account_data.acc,
            register_account_data.pwd,
            name,
            identity_num,
            phone_num,
            (int)register_account_data.sex_type);

        MySqlConnection con = new MySqlConnection(ConStr);
        con.Open();

        MySqlCommand cmd = con.CreateCommand();
        cmd.CommandText = sql_str;

        MySQLRequest request = new MySQLRequest();
        request.con = con;
        request.cmd = cmd;

        RegisterResponseData result = new RegisterResponseData();
        result.result = _eProtocolResult.Failed;
        result.acc_name = request.acc_name;

        try
        {
            await Task<int>.Factory.FromAsync(cmd.BeginExecuteNonQuery(), cmd.EndExecuteNonQuery);

            sql_str = string.Format("SELECT AccountId From Account WHERE binary AccountName='{0}';", register_account_data.acc);
            cmd.CommandText = sql_str;
            MySqlDataReader data = await Task<MySqlDataReader>.Factory.FromAsync(cmd.BeginExecuteReader(), cmd.EndExecuteReader);

            var dt = new DataTable();
            dt.Load(data);
            data.Dispose();

            DataRow[] rows = dt.Select();
            if (rows.Length == 1)
            {
                result.result = _eProtocolResult.Success;
                result.acc_id = (ulong)((long)rows[0]["AccountId"]);

                EbLog.Note("AccountId=" + result.acc_id);
            }
        }
        catch (MySqlException ex)
        {
            EbLog.Note(ex.ToString());

            switch (ex.Number)
            {
                case 1062:
                    {
                        result.result = _eProtocolResult.RegisterAccountExist;
                        EbLog.Note("用户名重复, AccountName=" + register_account_data.acc);
                    }
                    break;
                default:
                    break;
            }
        }
        finally
        {
            request.con.Close();
            request.con.Dispose();
            request.cmd.Dispose();
        }

        return result;
    }

    //-------------------------------------------------------------------------
    public async Task<LoginResponseData> login(string account_name, string password)
    {
        string sql_str = string.Format("SELECT * FROM Account WHERE binary AccountName='{0}' AND binary Password='{1}' ;",
            account_name, password);

        MySqlConnection con = new MySqlConnection(ConStr);
        con.Open();

        MySqlCommand cmd = con.CreateCommand();
        cmd.CommandText = sql_str;

        LoginResponseData d = new LoginResponseData();
        d.result = _eProtocolResult.Failed;
        d.acc_name = account_name;

        try
        {
            MySqlDataReader data = await Task<MySqlDataReader>.Factory.FromAsync(cmd.BeginExecuteReader(), cmd.EndExecuteReader);
            var dt = new DataTable();
            dt.Load(data);
            data.Dispose();

            DataRow[] rows = dt.Select();
            if (rows.Length == 1)
            {
                d.result = _eProtocolResult.Success;
                d.acc_id = (ulong)((long)rows[0]["AccountId"]);
                d.sex = (SexType)(int)rows[0]["Sex"];
                d.et_player_guid = (string)rows[0]["TexasPokerPlayerGuid"];
            }
            else
            {
                d.result = _eProtocolResult.LoginAccountNotExist;
                d.acc_id = 0;
            }
        }
        catch (System.Exception ex)
        {
            EbLog.Error("DbClientMySQL.login() Exception: " + ex);
            d.result = _eProtocolResult.Failed;
            d.acc_id = 0;
            goto End;
        }

        if (d.result == _eProtocolResult.Success && string.IsNullOrEmpty(d.et_player_guid) && d.acc_id != 0)
        {
            string et_player_guid = Guid.NewGuid().ToString();
            sql_str = string.Format("UPDATE Account set TexasPokerPlayerGuid='{0}' WHERE AccountId={1};", et_player_guid, d.acc_id);
            cmd.CommandText = sql_str;

            try
            {
                await Task<int>.Factory.FromAsync(cmd.BeginExecuteNonQuery(), cmd.EndExecuteNonQuery);
                d.et_player_guid = et_player_guid;
            }
            catch (System.Exception ex)
            {
                EbLog.Error("DbClientMySQL.login() Exception: " + ex);
                d.result = _eProtocolResult.Failed;
                d.et_player_guid = "";
                goto End;
            }
        }

        End:
        con.Close();
        con.Dispose();
        cmd.Dispose();

        return d;
    }
}
